package com.yinhe.music.yhmusic.constants;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;

import com.yinhe.music.yhmusic.log.MLog;

import java.io.File;

/**
 * Created by xujiexing on 14-6-12.
 */
public class BasicConfig {
    public static final int PHONE_LOW = 0;
    public static final int PHONE_MIDDLE = 1;
    public static final int PHONE_HIGH = 2;
    private Context mContext;
    private boolean isDebuggable;
    private File mLogDir;
    private File mRoot;
    private File mConfigDir;
    private File mMusicDownload;
    private File mLyricDir;
    private File mImageDir;

    private static BasicConfig mInstance;
    public int phoneType = PHONE_HIGH;
    public int defaultPhoneType = -1;

    public void setPhoneType(int phoneType) {
        this.phoneType = phoneType;
        if(this.defaultPhoneType == -1){
            this.defaultPhoneType = phoneType;
        }
    }

    public void resetPhoneType(){
        this.phoneType = this.defaultPhoneType == -1
                ? PHONE_LOW
                : this.defaultPhoneType;
    }

    public synchronized static BasicConfig getInstance(){
        if(mInstance == null) {
            mInstance = new BasicConfig();
        }
        return mInstance;
    }

    private BasicConfig(){

    }

    public void setAppContext(Context context){
        mContext = context;
        setDebuggable(isDebugMode(context));
    }

    private boolean isDebugMode(Context context) {
        boolean debuggable = false;
        ApplicationInfo appInfo = null;
        PackageManager packMgmr = context.getPackageManager();
        if (packMgmr == null){
            return false;
        }
        try {
            appInfo = packMgmr.getApplicationInfo(context.getPackageName(),
                    PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            MLog.error(this, e);
        }
        if (appInfo != null) {
            debuggable = (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) > 0;
        }
        MLog.verbose(this, "isDebugMode debuggable = %b", debuggable);
        return debuggable;
    }

    public Context getAppContext(){
        return mContext;
    }

    public boolean isDebuggable(){
        return isDebuggable;
    }

    public void setDebuggable(boolean debuggable){
        isDebuggable = debuggable;
    }

    public void setRootDir(String rootDir){
    	File f = getCacheDir(mContext, rootDir);
    	if (f != null || !f.exists()){
    		f.mkdirs();
    	}
        this.mRoot = f;
    }

    public File getRootDir(){
        return this.mRoot;
    }

    /**
     * 设置config的目录
     * @param dir
     */
    public void setConfigDir(String dir){
        try {
            mConfigDir = getCacheDir(mContext, dir);
            if (!mConfigDir.exists() && !mConfigDir.mkdirs()){
                MLog.error(this, "Can't create config dir " + mConfigDir);
                return;
            }
        } catch (Exception e) {
            MLog.error(this, "Set config dir ERROR", e);
        }
    }

    public File getConfigDir(){
        return mConfigDir;
    }

    public void setMusicDownLoadDir(String dir){
        try {
            mMusicDownload = getCacheDir(mContext, dir);
            if (!mMusicDownload.exists() && !mMusicDownload.mkdirs()){
                MLog.error(this, "Can't create mMusicDownload dir " + mMusicDownload);
                return;
            }
        } catch (Exception e) {
            MLog.error(this, "Set mMusicDownload dir ERROR", e);
        }
    }



    public File getImageDir(){
        return mImageDir;
    }


    public void setImageDir(String dir){
        try {
            mImageDir = getCacheDir(mContext, dir);
            if (!mImageDir.exists() && !mImageDir.mkdirs()){
                MLog.error(this, "Can't create mImageDir dir " + mImageDir);
                return;
            }
        } catch (Exception e) {
            MLog.error(this, "Set mImageDir dir ERROR", e);
        }
    }

    public File getMusicDownLoadDir(){
        return mMusicDownload;
    }

    public File getLyricDir(){
        return mLyricDir;
    }

    public void setLyricDir(String dir){
        try {
            mLyricDir = getCacheDir(mContext, dir);
            if (!mLyricDir.exists() && !mLyricDir.mkdirs()){
                MLog.error(this, "Can't create config dir " + mLyricDir);
                return;
            }
        } catch (Exception e) {
            MLog.error(this, "Set config dir ERROR", e);
        }
    }



    /**
     * 设置log的目录
     * @param dir
     */
    public void setLogDir(String dir){
        try {
            mLogDir = getCacheDir(mContext, dir);
            if (!mLogDir.exists() && !mLogDir.mkdirs()){
                MLog.error(this, "Can't create log dir " + mLogDir);
                return;
            }

        } catch (Exception e) {
            MLog.error(this, "Set log dir ERROR", e);
        }
    }

    public File getLogDir(){
        return mLogDir;
    }

    public boolean isExternalStorageAvailable() {
        return mExternalStorageAvailable;
    }

    public boolean isExternalStorageWriteable() {
        return mExternalStorageWriteable;
    }

    BroadcastReceiver mExternalStorageReceiver;
    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;

    public void startExternalState() {
        updateExternalStorageState();
        startWatchingExternalStorage();
    }

    public void updateExternalStorageState() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            mExternalStorageAvailable = mExternalStorageWriteable = true;
        } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            mExternalStorageAvailable = true;
            mExternalStorageWriteable = false;
        } else {
            mExternalStorageAvailable = mExternalStorageWriteable = false;
        }
    }

    public void startWatchingExternalStorage() {
        if (mContext == null) {
            MLog.error(this, "mContext null when startWatchingExternalStorage");
            return;
        }
        mExternalStorageReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                MLog.info("ExternalStorageReceiver", "Storage: " + intent.getData());
                updateExternalStorageState();
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
        filter.addAction(Intent.ACTION_MEDIA_REMOVED);
        mContext.registerReceiver(mExternalStorageReceiver, filter);
        updateExternalStorageState();
    }

    public void stopWatchingExternalStorage() {
        if (mContext == null) {
            MLog.error(this, "mContext null when stopWatchingExternalStorage");
            return;
        }
        mContext.unregisterReceiver(mExternalStorageReceiver);
    }


    public static File getCacheDir(Context context, String uniqueName) {
        // Check if media is mounted or storage is built-in, if so, try and use external cache dir
        // otherwise use internal cache dir
        final String cachePath =
                BasicConfig.getInstance().isExternalStorageAvailable() ||
                        !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :
                        context.getCacheDir().getPath();

        return new File(cachePath + File.separator + uniqueName);
    }

    private static boolean isExternalStorageRemovable() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            return Environment.isExternalStorageRemovable();
        }
        return true;
    }

    private static File getExternalCacheDir(Context context) {
        return new File(Environment.getExternalStorageDirectory().getPath());
    }
}
